package com.dadovicn.repo.primary.fx.imp;

import com.dadovicn.constant.Constant;
import com.dadovicn.enums.DayOfWeekEnum;
import com.dadovicn.fx.ywb.YwbJqCjjlb;
import com.dadovicn.fx.ywb.dsl.QYwbJqCjjlb;
import com.dadovicn.fx.ywb.dsl.QYwbJqJjjlb;
import com.dadovicn.fx.ywb.dto.JcjDetailDTO;
import com.dadovicn.fx.ywb.dto.RecentMonthJjDTO;
import com.dadovicn.fx.ywb.dto.YjxxDTO;
import com.dadovicn.fx.ywb.dto.YwbJjjlbFissionDto;
import com.dadovicn.fx.ywb.qo.CalendarQO;
import com.dadovicn.fx.ywb.qo.CountQO;
import com.dadovicn.fx.ywb.qo.JcjQO;
import com.dadovicn.fx.ywb.vo.*;
import com.dadovicn.repo.primary.base.BaseQueryDsl;
import com.dadovicn.repo.primary.base.PoiUtil;
import com.dadovicn.repo.primary.fx.CommonRepo;
import com.dadovicn.repo.primary.fx.JcjRepo;
import com.dadovicn.util.DateUtil;
import com.dadovicn.web.Result;
import com.querydsl.core.BooleanBuilder;
import com.querydsl.core.Tuple;
import com.querydsl.core.types.Projections;
import com.querydsl.core.types.dsl.EntityPathBase;
import com.querydsl.core.types.dsl.Expressions;
import com.querydsl.core.types.dsl.StringTemplate;
import com.querydsl.jpa.impl.JPAQuery;
import com.sun.org.apache.regexp.internal.RE;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Field;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @desc 接处警查询实现
 * @author dadovicn
 * @date   2018/9/15
 */
@Slf4j
@Component
@Transactional
public class JcjRepoImp extends BaseQueryDsl implements JcjRepo {

    private static final String IN_VALID = "无效";
    /** 刑事案件 */
    private static final String XSAJ_DM = "01000000";
    @Resource
    private CommonRepo commonRepo;

    @Override
    public Result findJcjByJjbh(String jjbh) {
        QYwbJqJjjlb jjb = QYwbJqJjjlb.ywbJqJjjlb;
        JPAQuery<JcjDetailDTO> jpaQuery = queryFactory.select(Projections.bean(JcjDetailDTO.class,
            jjb.jjbh,
            jjb.lhlbmc,
            jjb.bjsj,
            jjb.sfrgsc,
            jjb.jjzt,
            jjb.cjbs,
            jjb.cfbj,
            jjb.jjrgh,
            jjb.jjrxm,
            jjb.bjdh,
            jjb.bjrlxdh,
            jjb.bjrxm,
            jjb.bjrxb,
            jjb.fadz,
            jjb.bjnr,
            jjb.jjlbmc,
            jjb.jjlxmc,
            jjb.jjxlmc,
            jjb.jjxxmc,
            jjb.gxdwmc,
            jjb.xqmc
                )).from(jjb).where(jjb.jjbh.eq(jjbh)).fetchAll();
        JcjDetailDTO jcjDetailDTO = jpaQuery.fetchFirst();
        return Result.success(jcjDetailDTO);
    }

    public Result findCjjByJjbh(String jjbh) {
        QYwbJqCjjlb cjb = QYwbJqCjjlb.ywbJqCjjlb;
        JPAQuery<YwbJqCjjlb> jpaQuery = queryFactory.select(cjb).from(cjb).where(cjb.jjbh.eq(jjbh));
        List<YwbJqCjjlb> re = jpaQuery.fetchAll().fetch();
        return Result.success(re);
    }

    public Result listJcj(JcjQO q, int currentPage, int pageSize) {
        QYwbJqJjjlb jjb = QYwbJqJjjlb.ywbJqJjjlb;
        QYwbJqCjjlb cjb = QYwbJqCjjlb.ywbJqCjjlb;
        Map<String, EntityPathBase> queryMap = new HashMap<String, EntityPathBase>() {{
            put("QYwbJqJjjlb", jjb);
            put("QYwbJqCjjlb", cjb);
        }};
        BooleanBuilder builder = new BooleanBuilder();
        genCondition(builder, q, queryMap);
        JPAQuery<YwbJjjlbFissionDto> jpaQuery = queryFactory.select(Projections.bean(YwbJjjlbFissionDto.class,
                jjb.bjrlxdh,
                jjb.bjsj,
                jjb.bjnr,
                jjb.bjrxm,
                jjb.jjbh,
                cjb.cjbh,
                jjb.jjlbmc,
                jjb.bjrxb,
                cjb.cjrxm))
                .from(jjb, cjb)
                .where(builder).orderBy(jjb.bjsj.desc()).fetchAll();
        if(pageSize == 0) {
            return Result.success(jpaQuery.fetch());
        }
        jpaQuery = jpaQuery.offset(currentPage * pageSize).limit(pageSize);
        return Result.success(jpaQuery.fetch(), jpaQuery.fetchCount());
    }

    @Override
    public void jcjExport(JcjQO q, HttpServletResponse response) {
        Result result = listJcj(q, 0, 0);
        String title = LocalDateTime.now().format(DateTimeFormatter.ofPattern(Constant.DATE_FOR_DOWNLOAD));
        PoiUtil.exportExcel((List<YwbJjjlbFissionDto>)result.getData(),title + "接处警查询导出数据","sheet1", YwbJjjlbFissionDto.class,title+ "接处警导出数据.xls", response);
    }

    @Override
    public Result countYwbJqJjjlbToday() {
        QYwbJqJjjlb jjb = QYwbJqJjjlb.ywbJqJjjlb;
        Map<String, Object> resultMap = new HashMap<>();
        LocalDateTime today = getMidNight(0);
        JPAQuery jpaQuery = queryFactory.select(jjb.jjbh).from(jjb).where(jjb.bjsj.gt(today)).fetchAll();
        Long count = jpaQuery.fetchCount();
        resultMap.put("total", count);
        LocalDateTime greatTime = getMinusNow(1); // 昨天下载
        LocalDateTime lessTime = getMidNight(1); // 昨天凌晨
        jpaQuery = queryFactory.select(jjb)
                .from(jjb)
                .where(jjb.bjsj.gt(lessTime).and(jjb.bjsj.before(greatTime)))
                .fetchAll();
        Long yesterdayCount = jpaQuery.fetchCount();
        double dod = ((count*1.0 - yesterdayCount*1.0) / yesterdayCount * 1.0) * 100;
        resultMap.put("dod", dod);
        resultMap.put("yesterdayCount", yesterdayCount);
        return Result.success(resultMap);
    }

    @Override
    public Result countYwbJqCjjlbToday() {
        QYwbJqCjjlb cjjlb = QYwbJqCjjlb.ywbJqCjjlb;
        Map<String, Object> resultMap = new HashMap<>();
        JPAQuery jpaQuery = queryFactory.select(cjjlb.jjbh).from(cjjlb).where(cjjlb.pfsj.gt(getMidNight(0))).fetchAll();
        Long count = jpaQuery.fetchCount();
        resultMap.put("total", count);
        jpaQuery = queryFactory.select(cjjlb.jjbh).from(cjjlb)
                .where(cjjlb.pfsj.lt(getMinusNow(1)).and(cjjlb.pfsj.gt(getMidNight(1))))
                .fetchAll();
        Long yesterdayCount = jpaQuery.fetchCount();
        double dod = ((count*1.0 - yesterdayCount*1.0) / yesterdayCount * 1.0) * 100;
        resultMap.put("dod", dod);
        resultMap.put("yesterdayCount", yesterdayCount);
        return Result.success(resultMap);
    }

    @Override
    public Result countYwbJqJjjlbValid() {
        QYwbJqJjjlb qYwbJqJjjlb = QYwbJqJjjlb.ywbJqJjjlb;
        JPAQuery jpaQuery = queryFactory.select(qYwbJqJjjlb).from(qYwbJqJjjlb).where(qYwbJqJjjlb.lhlbmc.ne("无效")
        .and(qYwbJqJjjlb.bjsj.gt(getMidNight(0)))).fetchAll();
        List<Coordinate> result = new ArrayList<>();
        result.add(new Coordinate("有效", jpaQuery.fetchCount()));
        jpaQuery = queryFactory.select(qYwbJqJjjlb).from(qYwbJqJjjlb).where(qYwbJqJjjlb.lhlbmc.eq("无效").and(qYwbJqJjjlb.bjsj.gt(getMidNight(0)))).fetchAll();
        result.add(new Coordinate("无效", jpaQuery.fetchCount()));
        return Result.success(result);
    }

    /**
     * 当日刑事案件总量
     * @return
     */
    @Override
    public Result countXsajToday() {
        QYwbJqJjjlb jjb = QYwbJqJjjlb.ywbJqJjjlb;
        Map<String, Object> resultMap = new HashMap<>();
        LocalDateTime today = getMidNight(0);
//        LocalDateTime today = getMidNight(60);
        JPAQuery jpaQuery = queryFactory.select(jjb.jjbh).from(jjb).where(jjb.bjsj.gt(today).and(jjb.jjbjlb.eq(XSAJ_DM))).fetchAll();
        Long count = jpaQuery.fetchCount();
        resultMap.put("total", count);
        // LocalDateTime greatTime = getMinusNow(1); // 昨天下载
         LocalDateTime greatTime = getMinusNow(1); // 昨天下载
//
        LocalDateTime lessTime = getMidNight(1); // 昨天凌晨
        jpaQuery = queryFactory.select(jjb)
                .from(jjb)
                .where(jjb.bjsj.gt(lessTime).and(jjb.bjsj.before(greatTime)).and(jjb.jjbjlb.eq(XSAJ_DM)))
                .fetchAll();
        Long yesterdayCount = jpaQuery.fetchCount();
        resultMap.put("yesterdayCount", yesterdayCount);
        double dod = ((count*1.0 - yesterdayCount*1.0) / yesterdayCount * 1.0) * 100;
        resultMap.put("dod", dod);
        return Result.success(resultMap);
    }

    @Override
    public Result listHighFreq(CountQO qo) {
        QYwbJqJjjlb qYwbJqJjjlb = QYwbJqJjjlb.ywbJqJjjlb;
        JPAQuery jpaQuery = queryFactory.select(Projections.bean(ClassAndCountVO.class, qYwbJqJjjlb.jjxlmc.count().as("value"), qYwbJqJjjlb.jjxlmc.as("name")))
                .from(qYwbJqJjjlb)
                .where(qYwbJqJjjlb.lhlbmc.ne("无效").and(qYwbJqJjjlb.jjlbmc.isNotNull())
                        .and(qYwbJqJjjlb.bjsj.gt(qo.getDate().get(0))).and(qYwbJqJjjlb.bjsj.lt(qo.getDate().get(1)))
                )
                .groupBy(qYwbJqJjjlb.jjxlmc).fetchAll();
        List<ClassAndCountVO> highFreq = jpaQuery.fetch();
        highFreq = highFreq.stream().map( i -> new ClassAndCountVO(i.getValue(), i.getName())).collect(Collectors.toList());
        return Result.success(highFreq);
    }

    @Override
    public Result primaryMonitor(CountQO qo) {
        QYwbJqJjjlb q = QYwbJqJjjlb.ywbJqJjjlb;
        JPAQuery jpaQuery = queryFactory.select(Projections.bean(Coordinate.class, q.jjlbmc.count().as("y"), q.jjlbmc.as("x")))
                .from(q)
                .where(
                        q.lhlbmc.ne("无效")
                        .and(q.jjlbmc.isNotNull())
                        .and(q.bjsj.gt(qo.getDate().get(0)))
                        .and(q.bjsj.lt(qo.getDate().get(1)))
                )
                .groupBy(q.jjlbmc).fetchAll();
        return trans(jpaQuery);
    }

    @Override
    public Result primaryMonitorForCj(CountQO qo) {
        QYwbJqJjjlb jj = QYwbJqJjjlb.ywbJqJjjlb;
        QYwbJqCjjlb cj = QYwbJqCjjlb.ywbJqCjjlb;
        JPAQuery jpaQuery = queryFactory.select(Projections.bean(Coordinate.class, jj.jjlbmc.as("x"), jj.jjlbmc.count().as("y")))
                .from(jj, cj)
                .where(
                        jj.jjbh.eq(cj.jjbh)
                        .and(cj.pfsj.gt(qo.getDate().get(0)))
                        .and(cj.pfsj.lt(qo.getDate().get(1))))
                .groupBy(jj.jjlbmc)
                .fetchAll();
        return trans(jpaQuery);
    }

    @Override
    public Result xqRanking(CountQO qo) {
        QYwbJqJjjlb q = QYwbJqJjjlb.ywbJqJjjlb;
        JPAQuery jpaQuery = queryFactory.select(Projections.bean(RankVO.class, q.xqmc.count().as("total"), q.xqmc.as("title")))
                .from(q)
                .where(
                        q.lhlbmc.ne("无效")
                        .and(q.xqmc.isNotNull())
                        .and(q.bjsj.gt(qo.getDate().get(0)))
                        .and(q.bjsj.lt(qo.getDate().get(1)))
                )
                .groupBy(q.xqmc)
                .orderBy(q.xqmc.count().desc())
                .fetchAll();
        return transXq(jpaQuery);
    }

    @Override
    public Result xqRankingCj(CountQO qo) {
        QYwbJqJjjlb jj = QYwbJqJjjlb.ywbJqJjjlb;
        QYwbJqCjjlb cj = QYwbJqCjjlb.ywbJqCjjlb;
        JPAQuery jpaQuery = queryFactory.select(Projections.bean(RankVO.class, jj.xqmc.count().as("total"), jj.xqmc.as("title")))
                .from(jj, cj)
                .where(
                        jj.jjbh.eq(cj.jjbh)
                        .and(jj.xqmc.isNotNull())
                        .and(cj.pfsj.gt(qo.getDate().get(0)))
                        .and(cj.pfsj.lt(qo.getDate().get(1)))
                )
                .groupBy(jj.xqmc)
                .orderBy(jj.xqmc.count().desc())
                .fetchAll();
        return transXq(jpaQuery);
    }

    @Override
    public Result getCalendarhorizontalData(CalendarQO calendarQO) {
        QYwbJqJjjlb q = QYwbJqJjjlb.ywbJqJjjlb;
        StringTemplate tmp = Expressions.stringTemplate("TO_CHAR({0},'yyyy-mm-dd')", q.bjsj);
        BooleanBuilder builder = new BooleanBuilder();
        List<String> bjlbdmList = calendarQO.getBjlbdmList();
        if(bjlbdmList != null && bjlbdmList.size() > 0) {
            int size = bjlbdmList.size();
            switch (size) {
                case 1: builder.and(q.jjbjlb.eq(bjlbdmList.get(0)));
                    break;
                case 2: builder.and(q.jjbjlx.eq(bjlbdmList.get(1)));
                    break;
                case 3: builder.and(q.jjbjxl.eq(bjlbdmList.get(2)));
                    break;
                    default: break;
            }
        }
        if(StringUtils.isNotEmpty(calendarQO.getXqdm())) {
            builder.and(q.xqdm.eq(calendarQO.getXqdm()));
        }
        builder.and(q.bjsj.gt(LocalDateTime.now().minusYears(1)));
        JPAQuery jpaQuery = queryFactory.select(Projections.bean(DayAndCountVO.class, q.bjsj.count().as("commits"), tmp.as("date")))
                .from(q)
                .where(builder)
                .groupBy(tmp).fetchAll();
        List<DayAndCountVO> result = jpaQuery.fetch();
        List<String> resultDays = result.stream().map(i -> i.getDate()).collect(Collectors.toList());
        List<String> allDays = DateUtil.genYearDate();
        allDays.removeAll(resultDays);
        List<DayAndCountVO> afterAllDays = allDays.stream().map(i -> new DayAndCountVO(i, 0L)).collect(Collectors.toList());
        result.addAll(afterAllDays);
        result.sort(new Comparator<DayAndCountVO>() {
            @Override
            public int compare(DayAndCountVO o1, DayAndCountVO o2) {
                if (LocalDate.parse(o1.getDate(), DateTimeFormatter.ISO_LOCAL_DATE).isBefore(LocalDate.parse(o2.getDate(), DateTimeFormatter.ISO_LOCAL_DATE))
                        ) {
                    return 1;
                }else {
                    return -1;
                }
            }
        });
        Collections.reverse(result);
        final int[] step = new int[1];
        ///todo 0001 这个方法需要优化
        List<DayAndCountVO> endResult = result.stream().map((DayAndCountVO i) -> {
            Integer day = DateUtil.getDayOfWeek(i.getDate());
            Integer month = DateUtil.getMonth(i.getDate());
            Integer week = step[0];
            if(day.equals(6)) {
                step[0] = step[0] + 1;
            }
            boolean lastDay = false;
            boolean lastWeek = false;
            LocalDate localDate =LocalDate.parse(i.getDate(), DateTimeFormatter.ISO_LOCAL_DATE);
            if(localDate.getDayOfMonth() > localDate.lengthOfMonth() -7) {
                lastWeek = true;
            }
            if(localDate.getDayOfMonth() == localDate.lengthOfMonth()) {
                lastDay = true;
            }
            return new DayAndCountVO(i.getDate(), i.getCommits(), month, day, week.toString(), lastDay, lastWeek);
        }).collect(Collectors.toList());
        return Result.success(endResult);
    }

    @Cacheable(value = "reportCache", key = "#root.methodName")
    public Result getHeatMap() {
        QYwbJqJjjlb q = QYwbJqJjjlb.ywbJqJjjlb;
        StringTemplate tmp = Expressions.stringTemplate("TO_CHAR({0},'yyyy-mm-dd')", q.bjsj);
        List<HeatMapVO> result = new ArrayList<>();
        JPAQuery<HeatMapVO> jpaQueryA = queryFactory.select(Projections.bean(HeatMapVO.class,q.jjlbmc.as("jjlbmc"), q.jjlbmc.count().as("count")))
                .from(q)
                .where(tmp.eq(LocalDate.now().minusDays(0).toString())
                        .and(q.jjlbmc.isNotNull()))
                .groupBy(q.jjlbmc).fetchAll();
        JPAQuery<HeatMapVO> jpaQueryB = queryFactory.select(Projections.bean(HeatMapVO.class,q.jjlbmc.as("jjlbmc"), q.jjlbmc.count().as("count")))
                .from(q)
                .where(tmp.eq(LocalDate.now().minusDays(1L).toString())
                        .and(q.jjlbmc.isNotNull()))
                .groupBy(q.jjlbmc).fetchAll();
        JPAQuery<HeatMapVO> jpaQueryC = queryFactory.select(Projections.bean(HeatMapVO.class,q.jjlbmc.as("jjlbmc"), q.jjlbmc.count().as("count")))
                .from(q)
                .where(tmp.eq(LocalDate.now().minusDays(2L).toString())
                        .and(q.jjlbmc.isNotNull()))
                .groupBy(q.jjlbmc).fetchAll();
        JPAQuery<HeatMapVO> jpaQueryD = queryFactory.select(Projections.bean(HeatMapVO.class,q.jjlbmc.as("jjlbmc"), q.jjlbmc.count().as("count")))
                .from(q)
                .where(tmp.eq(LocalDate.now().minusDays(3L).toString())
                        .and(q.jjlbmc.isNotNull()))
                .groupBy(q.jjlbmc).fetchAll();
        JPAQuery<HeatMapVO> jpaQueryE = queryFactory.select(Projections.bean(HeatMapVO.class,q.jjlbmc.as("jjlbmc"), q.jjlbmc.count().as("count")))
                .from(q)
                .where(tmp.eq(LocalDate.now().minusDays(4L).toString())
                        .and(q.jjlbmc.isNotNull()))
                .groupBy(q.jjlbmc).fetchAll();
        String A = LocalDate.now().minusDays(0).toString();
        List<HeatMapVO> heatMapVOA = transA(jpaQueryA.fetch().stream().map(i -> new HeatMapVO(A, i.getJjlbmc(), i.getCount())).collect(Collectors.toList()), A);
        String B = LocalDate.now().minusDays(1).toString();
        List<HeatMapVO> heatMapVOB = transA(jpaQueryB.fetch().stream().map(i -> new HeatMapVO(B, i.getJjlbmc(), i.getCount())).collect(Collectors.toList()), B);
        String C = LocalDate.now().minusDays(2).toString();
        List<HeatMapVO> heatMapVOC = transA(jpaQueryC.fetch().stream().map(i -> new HeatMapVO(C, i.getJjlbmc(), i.getCount())).collect(Collectors.toList()), C);
        String D = LocalDate.now().minusDays(3).toString();
        List<HeatMapVO> heatMapVOD = transA(jpaQueryD.fetch().stream().map(i -> new HeatMapVO(D, i.getJjlbmc(), i.getCount())).collect(Collectors.toList()), D);
        String E = LocalDate.now().minusDays(4).toString();
        List<HeatMapVO> heatMapVOE = transA(jpaQueryE.fetch().stream().map(i -> new HeatMapVO(E, i.getJjlbmc(), i.getCount())).collect(Collectors.toList()), E);
        heatMapVOA.addAll(heatMapVOB);
        heatMapVOA.addAll(heatMapVOC);
        heatMapVOA.addAll(heatMapVOD);
        heatMapVOA.addAll(heatMapVOE);
        return Result.success(heatMapVOA);
    }

    @Override
    public Result getRecentMonthJj() {
        QYwbJqJjjlb q = QYwbJqJjjlb.ywbJqJjjlb;
        StringTemplate tmp = Expressions.stringTemplate("TO_CHAR({0},'yyyy-mm-dd')", q.bjsj);
        JPAQuery jpaQuery = queryFactory.select(Projections.bean(RecentMonthJjDTO.class, q.bjsj.count().as("jjCount"), tmp.as("date")))
                .from(q)
//                .where(q.bjsj.gt(LocalDateTime.now().minusMonths(3)).and(q.bjsj.lt(LocalDateTime.now().minusMonths(2))))
                .where(q.bjsj.gt(LocalDateTime.now().minusMonths(1)))
                .groupBy(tmp).fetchAll();
        List<RecentMonthJjDTO> recentMonthJjDTOList = jpaQuery.fetch();
        List<String> resultDays = recentMonthJjDTOList.stream().map(i -> i.getDate()).collect(Collectors.toList());
        List<String> allDays = DateUtil.genMonthDate();
        allDays.removeAll(resultDays);
        List<RecentMonthJjDTO> afterAllDays = allDays.stream().map(i -> new RecentMonthJjDTO(0L, i)).collect(Collectors.toList());
        recentMonthJjDTOList.addAll(afterAllDays);
        // 就这样吧
        recentMonthJjDTOList.sort(new Comparator<RecentMonthJjDTO>() {
            @Override
            public int compare(RecentMonthJjDTO o1, RecentMonthJjDTO o2) {
                if (LocalDate.parse(o1.getDate(), DateTimeFormatter.ISO_LOCAL_DATE).isBefore(LocalDate.parse(o2.getDate(), DateTimeFormatter.ISO_LOCAL_DATE))
                        ) {
                    return 1;
                }else {
                    return -1;
                }
            }
        });
        Collections.reverse(recentMonthJjDTOList);
        return Result.success(recentMonthJjDTOList);
    }

    @Override
    public Result getDayRate() {
        QYwbJqJjjlb q = QYwbJqJjjlb.ywbJqJjjlb;
        LocalDateTime greatTime = LocalDateTime.now();
        LocalDateTime lessTime = getMidNight(0); // 昨天凌晨

        Map<String, Object> allBjlbMapToday = this.commonRepo.findAllBjlbMap();
        Map<String, Object> allBjlbMapYestoday = this.commonRepo.findAllBjlbMap();
        Map<String, Object> todayMap = new HashMap<>();
        queryFactory.select(q.jjlbmc, q.jjlbmc.count())
            .from(q)
            .where(
                    q.lhlbmc.ne("无效")
                            .and(q.jjlbmc.isNotNull())
                    .and(q.bjsj.gt(lessTime))
                    .and(q.bjsj.lt(greatTime))
             )
            .groupBy(q.jjlbmc).fetch().stream().forEach( truple -> {
            todayMap.put((String)truple.get(q.jjlbmc),truple.get(q.jjlbmc.count()));
        });
        allBjlbMapToday.putAll(todayMap);

        Map<String, Object> yesterdayMap = new HashMap<>();
        LocalDateTime ygreatTime = getMinusNow(1);
        LocalDateTime ylessTime = getMidNight(1);
        queryFactory.select(q.jjlbmc, q.jjlbmc.count())
                .from(q)
                .where(
                        q.lhlbmc.ne("无效")
                                .and(q.jjlbmc.isNotNull())
                                .and(q.bjsj.gt(ylessTime))
                                .and(q.bjsj.lt(ygreatTime))
                )
                .groupBy(q.jjlbmc).fetch().stream().forEach( truple -> {
            yesterdayMap.put((String)truple.get(q.jjlbmc),truple.get(q.jjlbmc.count()));
        });
        allBjlbMapYestoday.putAll(yesterdayMap);

        Map<String, Object> totalMap = this.cutWeight(allBjlbMapToday, allBjlbMapYestoday);
        allBjlbMapToday.put("name", "今天");
        allBjlbMapYestoday.put("name", "昨天");
        totalMap.put("name", "合计");

        List result = new ArrayList();
        result.add(allBjlbMapYestoday);
        result.add(allBjlbMapToday);
        result.add(totalMap);
        return Result.success(result);
     }

    @Override
    @Cacheable(value = "reportCache", key = "#root.methodName")
    public Result getWeekRate() {
        QYwbJqJjjlb q = QYwbJqJjjlb.ywbJqJjjlb;
        LocalDateTime greatTime = LocalDateTime.now();
        LocalDateTime lessTime = greatTime.minusDays(greatTime.getDayOfWeek().getValue());
        Map<String, Object> allBjlbMapToday = this.commonRepo.findAllBjlbMap();
        Map<String, Object> allBjlbMapYestoday = this.commonRepo.findAllBjlbMap();
        Map<String, Object> todayMap = new HashMap<>();

        queryFactory.select(q.jjlbmc, q.jjlbmc.count())
                .from(q)
                .where(
                        q.lhlbmc.ne("无效")
                                .and(q.jjlbmc.isNotNull())
                                .and(q.bjsj.gt(lessTime))
                                .and(q.bjsj.lt(greatTime))
                )
                .groupBy(q.jjlbmc).fetch().stream().forEach( truple -> {
            todayMap.put((String)truple.get(q.jjlbmc), (Long)truple.get(q.jjlbmc.count()));
        });
        allBjlbMapToday.putAll(todayMap);

        Map<String, Object> yesterdayMap = new HashMap<>();
        LocalDateTime ygreatTime = greatTime.minusWeeks(1);
        LocalDateTime ylessTime = ygreatTime.minusDays(ygreatTime.getDayOfWeek().getValue());
        queryFactory.select(q.jjlbmc, q.jjlbmc.count())
                .from(q)
                .where(
                        q.lhlbmc.ne("无效")
                                .and(q.jjlbmc.isNotNull())
                                .and(q.bjsj.gt(ylessTime))
                                .and(q.bjsj.lt(ygreatTime))
                )
                .groupBy(q.jjlbmc).fetch().stream().forEach( truple -> {
            yesterdayMap.put((String)truple.get(q.jjlbmc), (Long)truple.get(q.jjlbmc.count()));
        });
        allBjlbMapYestoday.putAll(yesterdayMap);
        Map<String, Object> totalMap = this.cutWeight(allBjlbMapToday, allBjlbMapYestoday);
        allBjlbMapToday.put("name", "本周");
        allBjlbMapYestoday.put("name", "上周同期");
        totalMap.put("name", "合计");

        List result = new ArrayList();
        result.add(allBjlbMapYestoday);
        result.add(allBjlbMapToday);
        result.add(totalMap);
        return Result.success(result);
    }

    @Override
    @Cacheable(value = "reportCache", key = "#root.methodName")
    public Result getMonthRate() {
        QYwbJqJjjlb q = QYwbJqJjjlb.ywbJqJjjlb;
        LocalDateTime greatTime = LocalDateTime.now();
        LocalDateTime lessTime = greatTime.withDayOfMonth(1);
        Map<String, Object> todayMap = new HashMap<>();
        Map<String, Object> allBjlbMapToday = this.commonRepo.findAllBjlbMap();
        Map<String, Object> allBjlbMapYestoday = this.commonRepo.findAllBjlbMap();
        queryFactory.select(q.jjlbmc, q.jjlbmc.count())
                .from(q)
                .where(
                        q.lhlbmc.ne("无效")
                                .and(q.jjlbmc.isNotNull())
                                .and(q.bjsj.gt(lessTime))
                                .and(q.bjsj.lt(greatTime))
                )
                .groupBy(q.jjlbmc).fetch().stream().forEach( truple -> {
            todayMap.put((String)truple.get(q.jjlbmc), (Long)truple.get(q.jjlbmc.count()));
        });
        allBjlbMapToday.putAll(todayMap);
        Map<String, Object> yesterdayMap = new HashMap<>();
        LocalDateTime ygreatTime = LocalDateTime.now().minusMonths(1);
        LocalDateTime ylessTime = ygreatTime.withDayOfMonth(1);
        queryFactory.select(q.jjlbmc, q.jjlbmc.count())
                .from(q)
                .where(
                        q.lhlbmc.ne("无效")
                                .and(q.jjlbmc.isNotNull())
                                .and(q.bjsj.gt(ylessTime))
                                .and(q.bjsj.lt(ygreatTime))
                )
                .groupBy(q.jjlbmc).fetch().stream().forEach( truple -> {
            yesterdayMap.put((String)truple.get(q.jjlbmc), (Long)truple.get(q.jjlbmc.count()));
        });
        allBjlbMapYestoday.putAll(yesterdayMap);
        Map<String, Object> totalMap = this.cutWeight(allBjlbMapToday, allBjlbMapYestoday);
        allBjlbMapToday.put("name", "当月");
        allBjlbMapYestoday.put("name", "上月同期");
        totalMap.put("name", "合计");

        List result = new ArrayList();
        result.add(allBjlbMapYestoday);
        result.add(allBjlbMapToday);
        result.add(totalMap);
        return Result.success(result);    }

    @Override
    @Cacheable(value = "reportCache", key = "#root.methodName")
    public Result getWarnMonth() {
        CountQO countQO = new CountQO();
        List<LocalDateTime> dateTimes = new ArrayList<>();
        dateTimes.add(LocalDateTime.now().minusMonths(1));
        dateTimes.add(LocalDateTime.now());
        countQO.setDate(dateTimes);
        return this.primaryMonitor(countQO);
    }

    @Override
    public Result getWarnDay() {
        CountQO countQO = new CountQO();
        List<LocalDateTime> dateTimes = new ArrayList<>();
        dateTimes.add(getMidNight(0));
        dateTimes.add(LocalDateTime.now());
        countQO.setDate(dateTimes);
        return this.primaryMonitor(countQO);
    }

    @Override
    @Cacheable(value = "reportCache", key = "#root.methodName")
    public Result getWarnWeek() {
        CountQO countQO = new CountQO();
        List<LocalDateTime> dateTimes = new ArrayList<>();
        dateTimes.add(LocalDateTime.now().minusWeeks(1));
        dateTimes.add(LocalDateTime.now());
        countQO.setDate(dateTimes);
        return this.primaryMonitor(countQO);
    }

    /**
     * 获取几天前凌晨时间
     * @param minusDays
     * @return
     */
    private LocalDateTime getMidNight(long minusDays) {
        return LocalDateTime.of(LocalDate.now().minusDays(minusDays), LocalTime.MIN);
    }

    /**
     * 获取几天前的当前时间
     * @param minusDays
     * @return
     */
    private LocalDateTime getMinusNow(long minusDays) {
        return LocalDateTime.now().minusDays(minusDays);
    }

    /**
     * 案件类型拼接
     * @param jpaQuery
     * @return
     */
    private Result trans(JPAQuery jpaQuery) {
        List<Coordinate> coordinates = jpaQuery.fetch();
        List<String> lbmcList = coordinates.stream().map(i -> i.getX()).collect(Collectors.toList());
        List<String> bjlbAll = this.commonRepo.findAllBjlb();
        bjlbAll.removeAll(lbmcList);
        List<Coordinate> afterList = bjlbAll.stream().map(i -> new Coordinate(i, 0L)).collect(Collectors.toList());
        coordinates.addAll(afterList);
        return Result.success(coordinates);
    }

    private List<HeatMapVO> transA(List<HeatMapVO> heatMapVOS, String day) {
        List<String> lbmcList = heatMapVOS.stream().map(i -> i.getJjlbmc()).collect(Collectors.toList());
        List<String> bjlbAll = this.commonRepo.findAllBjlb();
        bjlbAll.removeAll(lbmcList);
        List<HeatMapVO> afterList = bjlbAll.stream().map(i -> new HeatMapVO(day, i, 0L)).collect(Collectors.toList());
        heatMapVOS.addAll(afterList);
        return heatMapVOS;
    }

    /**
     * 辖区数据拼接
     * @param jpaQuery
     * @return
     */
    private Result transXq(JPAQuery jpaQuery) {
        List<RankVO> rankVOList = jpaQuery.fetch();
        List<String> xqmcList = rankVOList.stream().map(i -> i.getTitle()).collect(Collectors.toList());
        List<String> xqmcAll = this.commonRepo.findAllXQMC();
        xqmcAll.removeAll(xqmcList);
        List<RankVO> afterList = xqmcAll.stream().map(i -> new RankVO(i, 0L)).collect(Collectors.toList());
        rankVOList.addAll(afterList);
        return Result.success(rankVOList);
    }

    /**
     * map 两个map相减
     * @param goldMap
     * @param preMap
     * @return
     */
    private Map<String,Object> cutWeight(Map<String,Object> goldMap,Map<String,Object> preMap) {
        Map<String,Object> cutMap = new HashMap<String,Object>();
        for(String s : preMap.keySet())
        {
            if(goldMap.containsKey(s))
            {
                cutMap.put(s, ((Long)goldMap.get(s)-(Long)preMap.get(s)));

            } else
            {
                cutMap.put(s, -((Long)preMap.get(s)));
            }
        }
        for(String str : goldMap.keySet())
        {
            if(!preMap.containsKey(str))
            {
                cutMap.put(str, (Long)goldMap.get(str));
            }
        }

        return cutMap;
    }

    public static Map<String, Object> objectToMap(Object obj) throws IllegalAccessException {
        if(obj == null){
            return null;
        }
        Map<String, Object> map = new HashMap<String, Object>();
        Field[] declaredFields = obj.getClass().getDeclaredFields();
        for (Field field : declaredFields) {
            field.setAccessible(true);
            String filedName = field.getName();
            switch (filedName) {
                case "xsaj": map.put("刑事案件", field.get(obj)); break;
                case "zaaj": map.put("治安案件", field.get(obj)); break;
                case "qzqz": map.put("群众求助", field.get(obj)); break;
                case "jtljq": map.put("交通类警情", field.get(obj)); break;
                case "hzsg": map.put("火灾事故", field.get(obj)); break;
                case "jbts": map.put("举报投诉", field.get(obj)); break;
                case "shld": map.put("社会联动", field.get(obj)); break;
                case "qtxsj": map.put("群体性事件", field.get(obj)); break;
                case "zhsg": map.put("灾害事故", field.get(obj)); break;
                case "xzwf": map.put("行政违法", field.get(obj)); break;
                case "qtjq": map.put("其他警情", field.get(obj)); break;
                case "type": map.put("type", field.get(obj)); break;
                default: break;
            }
        }

        return map;
    }
}